/*
 * StreamEnd.h
 *
 *  Created on: 2011-3-29
 *      Author: hao
 */

#ifndef STREAMEND_H_
#define STREAMEND_H_

#include <string>
#include <functional>

class StreamTerminal {
public:

    virtual bool Init() = 0;

    virtual bool
    CreateStream(
            const std::function<bool(void *, size_t, size_t *)> & write_callback,
            const std::function<void()> & drain_callback,
            int sample_format, int channels, int rate) = 0;

    virtual bool DestroyStream() = 0;

    virtual void StreamStop() = 0;

    virtual void StreamStart() = 0;

    virtual void StreamPause() = 0;

    virtual void SetVolumeDB(double) {
    }

    virtual void SetVolumeLinear(double) {
    }

    virtual void ChannleSetVolumeDB(int, double) {
    }

    virtual void ChannleSetVolumeLinear(int, double) {
    }
    
    virtual unsigned long long getStreamCurrentTime(){
        return 0;
    }
    
    virtual ~StreamTerminal(){}
};

class StreamEnd : public StreamTerminal {
    std::string patch;

    void * streamEndHandle;

    bool (*init_function)();

    bool (*destroy_function)();

    bool (*CreateStream_function)(int sample_format, int channels, int rate);

    bool (*DestroyStream_function)();

    void (*StreamStop_function)();

    void (*StreamStart_function)();

    void (*StreamPause_function)();

    void (*setWriteCallback_function)(const std::function<bool(void *, size_t,
            size_t *)> & write_callback);

    void (*setDrainCallback_function)(
            const std::function<void()> & drain_callback);

    void (*SetVolumeDB_function)(double);

    void (*SetVolumeLinear_function)(double);

    void (*SetChannleVolumeDB_function)(int, double);

    void (*SetChannleVolumeLinear_function)(int, double);
    
    unsigned long long ( *SteamGetCurrentTime )();

public:
    StreamEnd(const char * szPath);

    bool Init();

    bool
    CreateStream(
            const std::function<bool(void *, size_t, size_t *)> & write_callback,
            const std::function<void()> & drain_callback,
            int sample_format, int channels, int rate);

    bool DestroyStream();

    void StreamStop();

    void StreamStart();

    void StreamPause();

    //可选调用
    void SetVolumeDB(double db);

    void SetVolumeLinear(double linear);

    void ChannleSetVolumeDB(int channle, double db);

    void ChannleSetVolumeLinear(int channle, double linear);
    
    unsigned long long getStreamCurrentTime();

    ~StreamEnd();
};

#endif /* STREAMEND_H_ */
